package com.umeox.watch.moto.contact.utils;


import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Service;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.provider.CallLog;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.RawContacts;
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;

import com.android.internal.telephony.ITelephony;
import com.umeox.moto.common.log.Logger;
import com.umeox.moto.common.utils.DateUtils;
import com.umeox.watch.moto.contact.BuildConfig;
import com.umeox.watch.moto.contact.model.ContactDetail;
import com.umeox.watch.moto.dataservice.DataProvider;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

public class Utils {
    /**
     * 获取库Phon表字段
     **/
    private static final String[] PHONES_PROJECTION = new String[]{
            Phone.DISPLAY_NAME, Phone.NUMBER, Photo.PHOTO_ID, Phone.RAW_CONTACT_ID, RawContacts.LAST_TIME_CONTACTED};
    /**
     * 联系人显示名称
     **/
    private static final int PHONES_DISPLAY_NAME_INDEX = 0;
    /**
     * 电话号码
     **/
    private static final int PHONES_NUMBER_INDEX = 1;
    /**
     * 头像ID
     **/
    private static final int PHONES_PHOTO_ID_INDEX = 2;
    /**
     * 联系人的ID
     **/
    private static final int PHONES_CONTACT_ID_INDEX = 3;
    /**
     * 最后一次通话时间
     **/
    private static final int PHONES_LAST_TIME_INDEX = 4;
    public static boolean is24Hour;
    private static final String TAG = "Utils";

    /**
     * 得到手机通讯录联系人信息
     **/
    public static ArrayList<ContactDetail> getPhoneContacts(Context mContext) {
        ContentResolver resolver = mContext.getContentResolver();
        ArrayList<ContactDetail> mContacts = new ArrayList<>();
        ContactDetail bean;
        // 获取手机联系人
        Cursor phoneCursor = null;

        try {
            phoneCursor = resolver.query(Phone.CONTENT_URI, PHONES_PROJECTION, null, null, Phone.RAW_CONTACT_ID + ", " + RawContacts.LAST_TIME_CONTACTED + " DESC");

            if (phoneCursor != null) {
                while (phoneCursor.moveToNext()) {
                    //得到联系人ID
                    long contactid = phoneCursor.getLong(PHONES_CONTACT_ID_INDEX);
                    //得到手机号码
                    String phoneNumber = phoneCursor.getString(PHONES_NUMBER_INDEX);
                    //得到联系人名称
                    String contactName = phoneCursor.getString(PHONES_DISPLAY_NAME_INDEX);
                    //当手机号码为空的或者为空字段 跳过当前循环
                    if (BuildConfig.DEBUG) {
                        Log.d(TAG, "getPhoneContacts contactid:" + contactid + " phoneNumber:" + phoneNumber + " Count:" + phoneCursor.getCount());
                    }

                    if (contactid == 0) {
                        continue;
                    }
                    bean = new ContactDetail();
                    if(!TextUtils.isEmpty(phoneNumber)){
                        phoneNumber = phoneNumber.replace(" ", "");
                    }
                    bean.setContactNumber(phoneNumber);
                    bean.setContactName(contactName);

                    String photoPath = "", photoUrl = "";
                    //手机联系人还是设备联系人
                    int contactType = 1;
                    String friendId = "";
                    ContentValues result;
                    try {
                        result = DataProvider.getContactByRawContactId(contactid);
                        if (BuildConfig.DEBUG) {
                            Log.d(TAG, "getPhoneContacts contactid:" + contactid + " phoneNumber:" + phoneNumber + " result:" + result);
                        }
                        if (result != null) {
                            contactType = (int) result.get(DataProvider.ContactProvider.TYPE);
                            friendId = (String) result.get(DataProvider.ContactProvider.FRIEND_ID);
                            photoUrl = (String) result.get(DataProvider.ContactProvider.PHOTO_URL);
                            photoPath = (String) result.get(DataProvider.ContactProvider.PHOTO_PATH);
                        } else {
                            //没找到则删除电话簿对应的联系人
                            deleteContact(mContext, contactid);
                            continue;
                        }
                        Logger.d("通过RAW_CONTACT_ID[" + contactid + "]查找FRIENT_ID[" + friendId + "]");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    /*联系人类型
                        0: 管理员增加
                        1: 管理员
                        2：APP关注者
                        3：设备好友
                    */
                    bean.setType(contactType);
                    bean.setFriendId(friendId);
                    bean.setContactPhotoPath(photoPath);
                    bean.setContactPhotoUrl(photoUrl);
                    if (BuildConfig.DEBUG) {
                        Log.d(TAG, "getPhoneContacts contact:" + bean.toString());
                    }
                    //最后一次通话时间
                    long lastTime = phoneCursor.getLong(PHONES_LAST_TIME_INDEX);
                    Pair<Long, Boolean> videoCallsLog = getLastVideoCallsLog(friendId);
                    long lastVideoTime = videoCallsLog.first;

                    String lastTimeContacted = "";
                    /*最后一次语音通话时间不为空  开始*/
                    if (lastTime > 0 && lastTime > lastVideoTime) {
                        Logger.e("最后一次通话为语音电话");
                        Date date = new Date(lastTime);
                        Calendar cal = Calendar.getInstance();
                        cal.setTime(date);

                        /**格林尼治标准时间开始年份  开始*/
                        if (cal.get(Calendar.YEAR) > 1970) {
                            lastTimeContacted = sessionTimeFormat(mContext, lastTime);
                            /**
                             * 开始
                             * 获取最后一次通话记录类型
                             */
                            String[] project = new String[]{
                                    CallLog.Calls.CACHED_NAME,
                                    CallLog.Calls.NUMBER,
                                    CallLog.Calls.NEW,
                                    CallLog.Calls.DATE,
                                    CallLog.Calls.TYPE
                            };

                            String where = CallLog.Calls.NUMBER + "=? ";
                            String[] args = new String[]{phoneNumber + ""};
                            String orders = CallLog.Calls.DATE + " desc";

                            Cursor allCallLogs = null;
                            try {
                                allCallLogs = resolver.query(CallLog.Calls.CONTENT_URI, project, where, args, orders);
                                if (allCallLogs != null && allCallLogs.moveToFirst()) {
                                    //最后一次通话类型
                                    int type = allCallLogs.getInt(allCallLogs.getColumnIndex(CallLog.Calls.TYPE));
                                    if (type == CallLog.Calls.MISSED_TYPE) {
                                        bean.setMissed(true);
                                    } else if (type == CallLog.Calls.INCOMING_TYPE) {
                                        bean.setInconming(true);
                                    } else if (type == CallLog.Calls.OUTGOING_TYPE) {
                                        bean.setOutgoing(true);
                                    }
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            } finally {
                                if (allCallLogs != null) {
                                    allCallLogs.close();
                                }
                            }

                            /**查看未接记录 开始*/
                            if (bean.isMissed()) {
                                where = CallLog.Calls.TYPE + "=? and " + CallLog.Calls.NUMBER + "=? and " + CallLog.Calls.NEW + "=?";
                                args = new String[]{CallLog.Calls.MISSED_TYPE + "", phoneNumber + "", "1"};
                                Cursor callLogs = resolver.query(CallLog.Calls.CONTENT_URI, project, where, args, CallLog.Calls.DEFAULT_SORT_ORDER);
                                if (callLogs != null && callLogs.getCount() > 0) {
                                    bean.setMissCount(callLogs.getCount());
                                    bean.setMissed(true);
                                    callLogs.close();
                                } else {
                                    bean.setMissed(false);
                                }
                            }/**查看未接记录 结束*/


                        }

                    }

                    /** 获取最后一次视频或者VOIP通话时间 开始*/
                    else
                    if (lastVideoTime > 0 && lastVideoTime > lastTime) {
                        Logger.e("最后一次通话为视频或者VOIP电话");
                        Date date = new Date(lastTime);
                        Calendar cal = Calendar.getInstance();
                        cal.setTime(date);
                        /**格林尼治标准时间开始年份  开始*/
                        if (cal.get(Calendar.YEAR) > 1970) {

                            lastTimeContacted = sessionTimeFormat(mContext, lastTime);
                        }
                        bean.setMissed(videoCallsLog.second);
                    }
                    /** 获取最后一次视频或者VOIP通话时间 结束*/
                    bean.setLastTimeContacted(lastTimeContacted);
                    mContacts.add(bean);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (phoneCursor != null) {
                phoneCursor.close();
            }
        }
        return mContacts;
    }

    public static ContactDetail getContactByFriendId(String friendId) {
        ContactDetail contactDetail = null;
        try {
            ContentValues result = DataProvider.getContactByFriendId(friendId);
            if (result != null) {
                contactDetail = new ContactDetail();
                contactDetail.setType(result.getAsInteger(DataProvider.ContactProvider.TYPE));
                contactDetail.setContactName(result.getAsString(DataProvider.ContactProvider.NICKNAME));
                contactDetail.setContactPhotoPath(result.getAsString(DataProvider.ContactProvider.PHOTO_PATH));
                contactDetail.setContactPhotoUrl(result.getAsString(DataProvider.ContactProvider.PHOTO_URL));
                contactDetail.setFriendId(result.getAsString(DataProvider.ContactProvider.FRIEND_ID));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return contactDetail;
    }

    public static final long DAYS = TimeUnit.DAYS.toMillis(1L);
    public static String sessionTimeFormat(Context ctx, long tagTime) {
        final SimpleDateFormat DATE_FORMAT_24 = new SimpleDateFormat("HH:mm", Locale.getDefault());
        final SimpleDateFormat DATE_FORMAT_12 = new SimpleDateFormat("hh:mm a", Locale.getDefault());
        final boolean hourFormat_24 = android.text.format.DateFormat.is24HourFormat(ctx);
        SimpleDateFormat dateFormat;
        final long intervalTime = System.currentTimeMillis() - tagTime;
        if (intervalTime >= DAYS) {
            dateFormat = new SimpleDateFormat("MM/dd HH:mm", Locale.getDefault());
        } else {
            dateFormat = DATE_FORMAT_24 ;
        }
        return dateFormat.format(tagTime);

    }


    private static boolean sameYear(Calendar tag, Calendar current) {
        return tag.get(Calendar.YEAR) == current.get(Calendar.YEAR);
    }

    private static boolean sameMonth(Calendar tag, Calendar current) {
        return tag.get(Calendar.MONTH) == current.get(Calendar.MONTH);
    }

    private static boolean sameDate(Calendar tag, Calendar current) {
        return sameYear(tag, current) && sameMonth(tag, current) && tag.get(Calendar.DAY_OF_MONTH) == current.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * Delete contacts who's rawContactid equals rawContactid
     *
     * @param rawContactid
     */
    private static void deleteContact(Context context, long rawContactid) {
        ArrayList<ContentProviderOperation> ops = new ArrayList<>();
        ops.add(ContentProviderOperation.newDelete(RawContacts.CONTENT_URI)
                .withSelection(RawContacts._ID + "=" + rawContactid, null)
                .build());
        try {
            context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
        } catch (Exception e) {
            Log.e("com.umeox.watch.contact", "Utils deleteContact: ", e);
        }
    }

    /**
     * 获取未接视频电话、VOIP电话记录
     */
    public static Pair<Long, Boolean> getLastVideoCallsLog(String friendId) {
        boolean missed = false;
        long lastTime = 0;
        ContentValues callLogs = DataProvider.getLastVideoCallLogs(friendId);
        if (callLogs != null) {
            long duration = (long) callLogs.get(DataProvider.VideoCallProvider.CALL_DURATION);
            boolean newCall = (int) callLogs.get(DataProvider.VideoCallProvider.NEW_CALL) == 1;
            missed = duration == 0 && newCall;
            lastTime = (long) callLogs.get(DataProvider.VideoCallProvider.END_TIME);
        }
        return new Pair<>(lastTime, missed);
    }

    /**
     * 获取上次通话记录，并且通话时长大于30秒
     */
    public static long getLastValidVideoCallsLog(String friendId) {
        ContentValues callLogs = DataProvider.getLastVideoCallLogs(friendId);
        if (callLogs != null) {
            long duration = (long) callLogs.get(DataProvider.VideoCallProvider.CALL_DURATION);
            if (duration > 30 * 1000) {
                return (long) callLogs.get(DataProvider.VideoCallProvider.END_TIME);
            }
        }
        return 0;
    }

    /**
     * 是否正在普通通话中
     */
    public static boolean isPhoneIdle(Context context) {
        Logger.w("系统当前版本：" + Build.VERSION.SDK_INT);
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            return !isInCall(context);
        }
        boolean isIdle = false;
        try {
            //反射获得系统服务的getService方法对象
            Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);
            //执行这个方法得到一个IBinder对象
            IBinder binder = (IBinder) method.invoke(null, new Object[]{"phone"});
            //转换为具体的服务类(ITelephony)接口对象
            ITelephony iTelephony = ITelephony.Stub.asInterface(binder);
            if (iTelephony != null) {
                isIdle = iTelephony.isIdle();
            }
        } catch (Exception e) {
        }
        return isIdle;
    }

    @SuppressLint("MissingPermission")
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private static boolean isInCall(Context context) {
        TelecomManager tm = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
        return tm.isInCall();
    }


    /**
     * 挂断电话
     */
    public static void endCall(Context ctx) {
        TelephonyManager mTelMgr = (TelephonyManager) ctx.getSystemService(Service.TELEPHONY_SERVICE);
        Class<TelephonyManager> c = TelephonyManager.class;
        try {
            @SuppressLint("PrivateApi")
            Method getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[]) null);
            getITelephonyMethod.setAccessible(true);
            ITelephony iTelephony;
            iTelephony = (ITelephony) getITelephonyMethod.invoke(mTelMgr, (Object[]) null);
            iTelephony.endCall();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static SharedPreferences getSpfs(Context context) {
        return context.getSharedPreferences("video_config", Context.MODE_PRIVATE);
    }

    public static int getVolume(Context context) {
        int defVolume = 200;
        SharedPreferences spf = getSpfs(context);
        if (spf != null) {
            return spf.getInt("current_volume", defVolume);
        }
        return defVolume;
    }

    public static void setVolume(Context context, int volume) {
        SharedPreferences spf = getSpfs(context);
        if (spf != null) {
            spf.edit().putInt("current_volume", volume).apply();
        }
    }


    public static void saveLog(String content) {
        if (!BuildConfig.DEBUG) {
            return;
        }
        final String message = DateUtils.formatDateTime(System.currentTimeMillis()) + " " + content;


        //创建一个带缓冲区的输出流
        String state = Environment.getExternalStorageState();
        if (state.equals(Environment.MEDIA_MOUNTED)) {
            String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
            String logPath = sdPath + "/CALL/log/";
            File file = new File(logPath);
            FileOutputStream fos = null;
            OutputStreamWriter writer = null;
            try {
                if (!file.exists()) {
                    file.mkdirs();
                }
                File logFile = new File(file, "log.txt");
                fos = new FileOutputStream(logFile, true);
                writer = new OutputStreamWriter(fos, "utf-8");
                writer.write(message);
                writer.write("\n");

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (writer != null) {
                        writer.close();
                    }

                    if (fos != null) {
                        fos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 根据电话号码查询联系人名称
     *
     * @param context  上下文对象
     * @param phoneNum 电话号码
     * @return
     */
    public static String getContactNameFromPhoneBook(Context context, String phoneNum) {
        Log.d(TAG, "getContactNameFromPhoneBook phoneNum:" + phoneNum);
        if (TextUtils.isEmpty(phoneNum)) {
            return "";
        }
        String number = phoneNum.replace(" ", "").replace("(", "").replace(")", "").replace("-", "");
        Log.d(TAG, "getContactNameFromPhoneBook number:" + number);
        String contactName = "";
        ContentResolver cr = context.getContentResolver();
        Cursor cursor = null;
        try {
            Uri lookupUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
                    Uri.encode(number));
            cursor = cr.query(lookupUri, null, null, null, null);
            if (cursor != null && cursor.moveToFirst()) {
                contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return contactName;
    }
}
